import {
  Injectable,
  InjectionToken,
  LoggerService as NestLoggerService,
  Scope,
  Inject,
} from '@nestjs/common';
import { Logger, LogMethod } from 'winston';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
/**
 * 自定义日志服务
 * 扩展NestJS的LoggerService接口，提供更多的日志功能
 */
@Injectable({ scope: Scope.TRANSIENT })
export class LoggerService implements NestLoggerService {
  private context?: string;

  constructor(
    @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
  ) {}

  /**
   * 设置日志上下文
   * @param context 上下文名称（通常是类名或模块名）
   */
  setContext(context: string) {
    this.context = context;
  }

  /**
   * 记录调试级别日志
   * @param message 日志消息
   * @param context 可选的上下文
   */
  debug(message: any, context?: string) {
    this.printMessage('debug', message, context);
  }

  /**
   * 记录详细级别日志
   * @param message 日志消息
   * @param context 可选的上下文
   */
  verbose(message: any, context?: string) {
    this.printMessage('verbose', message, context);
  }

  /**
   * 记录信息级别日志
   * @param message 日志消息
   * @param context 可选的上下文
   */
  log(message: any, context?: string) {
    this.printMessage('info', message, context);
  }

  /**
   * 记录警告级别日志
   * @param message 日志消息
   * @param context 可选的上下文
   */
  warn(message: any, context?: string) {
    this.printMessage('warn', message, context);
  }

  /**
   * 记录错误级别日志
   * @param message 日志消息
   * @param trace 错误堆栈
   * @param context 可选的上下文
   */
  error(message: any, trace?: string, context?: string) {
    const currentContext = context || this.context;

    if (message instanceof Error) {
      const { message: msg, name, stack } = message;
      this.logger.error({
        message: msg,
        errorName: name,
        stack: stack || trace,
        context: currentContext,
      });
      return;
    }

    this.logger.error({
      message,
      stack: trace,
      context: currentContext,
    });
  }

  /**
   * 记录HTTP请求日志
   * @param message 日志消息
   * @param context 可选的上下文
   */
  http(message: any, context?: string) {
    this.printMessage('http', message, context);
  }

  /**
   * 打印日志消息的内部方法
   * @param level 日志级别
   * @param message 日志消息
   * @param context 可选的上下文
   */
  private printMessage(level: string, message: any, context?: string) {
    const currentContext = context || this.context;
    const logMethod = this.logger[level as keyof Logger];

    if (message instanceof Object) {
      logMethod({
        message: JSON.stringify(message),
        context: currentContext,
      });
    } else {
      logMethod({
        message,
        context: currentContext,
      });
    }
  }
}
